package operativa.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import operativa.bean.entity.Cost;
import operativa.bean.entity.Location;
import operativa.model.dao.CostDAO;
import operativa.model.dao.LocationDAO;
import operativa.model.dto.CostosDTO;
import operativa.utils.Constantes.LocationType;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;

public class FishShopAbmAction extends ActionSupport implements ModelDriven<Location>, Preparable{
	

	private LocationDAO locationDAO = new LocationDAO();
	private CostDAO costDAO = new CostDAO();

	private static final long serialVersionUID = 1L;
	private List<Location> fishShopList;
	private Location fishShop = new Location();
	
	private List<CostosDTO> costos = new ArrayList<CostosDTO>();
	private Map<String, CostosDTO> costosMap = new HashMap<String, CostosDTO>();
	private List<Location> nodoList = new ArrayList<Location>();
	
	private boolean esEdicion = false;
	
	@Override
	public void prepare() throws Exception {
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		
		esEdicion =request.getParameter("id") != null && request.getParameter("id") != "";
		if (esEdicion){
			fishShop = locationDAO.findById(Integer.parseInt((request.getParameter("id"))),false);
		}
		nodoList = locationDAO.findAll();
		for (Location destino : nodoList) {
			CostosDTO nuevo = new CostosDTO(destino);
			costos.add(nuevo);
			costosMap.put(destino.getId().toString(), nuevo);
		}
	}
	
	/**
	 * Crea o actualiza un punto de destino
	 * @return
	 */
	public String save()
	{	
		this.fishShop.setType(LocationType.FISHSHOP.toString());
		this.locationDAO.makePersistent(fishShop);
		locationDAO.commit();
		nodoList.add(fishShop);
		// En este caso necesito guardar tanto el costo origen-destino, como destino-origen
		for (CostosDTO costo : costos) {
			Cost nuevo = new Cost();
			if (esEdicion){
				nuevo = costDAO.findCost(fishShop.getId(), costo.getDestino().getId());
			}
			else{
				nuevo = new Cost();
				nuevo.setOrigin(fishShop);
				nuevo.setDestination(costo.getDestino());
			}
			nuevo.setCost(costo.getCosto());
			
			Cost nuevo2 = new Cost();
			if (esEdicion){
				nuevo2 = costDAO.findCost(fishShop.getId(), costo.getDestino().getId());
			}
			else{
				nuevo2 = new Cost();
				nuevo2.setOrigin(costo.getDestino());
				nuevo2.setDestination(fishShop);
			}
			nuevo2.setCost(costo.getCosto());
			
			ArrayList<Cost> costoList = new ArrayList<Cost>();
			costoList.add(nuevo);
			System.out.println("COSTO 1: " + nuevo.getCost());
			costoList.add(nuevo2);
			System.out.println("COSTO 2: " + nuevo2.getCost());
			
			if (esEdicion)
				costDAO.persistUpdate(costoList);
			else
				costDAO.makePersistent(costoList);

		}
		this.refreshCostos();
		if (!costos.isEmpty())
			costDAO.commit();
		return SUCCESS;
	}
	
	private void refreshCostos(){
		costos.clear();
		costosMap.clear();
		for (Location destino : nodoList) {
			CostosDTO nuevo = new CostosDTO(destino);
			costos.add(nuevo);
			costosMap.put(destino.getId().toString(), nuevo);
		}
	}
	
	/**
	 * Crea o actualiza un punto de destino
	 * @return
	 */
	public String update()
	{	
		locationDAO.persistUpdate(fishShop);
		return SUCCESS;
	}
	
	/**
	 * Lista todas los puntos de destino
	 * @return
	 */
	public String list()
	{
		fishShopList = locationDAO.getByTipoUbicacion(LocationType.FISHSHOP.toString());
		nodoList = locationDAO.findAll();
		return SUCCESS;
	}
	
	/**
	 * Borra un punto de destino
	 * @return
	 */
	public String delete()
	{
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		Location toDelete = locationDAO.findById(Integer.parseInt(request.getParameter("id")), false);
		List<Cost> costosABorrar = costDAO.findAllContaining(toDelete.getId());
		costDAO.makeTransient(costosABorrar);
		costDAO.commit();
		locationDAO.makeTransient(toDelete);
		locationDAO.commit();
		return SUCCESS;
	}
	
	/**
	 * Obtiene un punto de destino segun un ID
	 * @return
	 */
	public String edit()
	{
		HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);
		fishShop = locationDAO.findById(Integer.parseInt((request.getParameter("id"))),false);
		return SUCCESS;
	}

	@Override
	public Location getModel() {
		return fishShop;
	}

	public List<Location> getFishShopList() {
		return fishShopList;
	}

	public void setFishShopList(List<Location> fishShopList) {
		this.fishShopList = fishShopList;
	}

	public Location getFishShop() {
		return fishShop;
	}

	public void setPuntoDestino(Location fishShop) {
		this.fishShop = fishShop;
	}

	public List<CostosDTO> getCostos() {
		return costos;
	}

	public void setCostos(List<CostosDTO> costos) {
		this.costos = costos;
	}

	public Map<String, CostosDTO> getCostosMap() {
		return costosMap;
	}

	public void setCostosMap(Map<String, CostosDTO> costosMap) {
		this.costosMap = costosMap;
	}

	public List<Location> getNodoList() {
		return nodoList;
	}

	public void setNodoList(List<Location> nodoList) {
		this.nodoList = nodoList;
	}
	

}